From b44cead2004e81dadcd436efc670bd075e0a5e9a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Sun, 3 Sep 2017 22:53:27 +0200 Subject: [PATCH] babl: add babl_fast_fish api --- babl/babl-fish-path.c | 77 +++++++++++++++++++++++++++++++++++-------- babl/babl.h | 24 ++++++++++++-- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c index 48629be..a383b14 100644 --- a/babl/babl-fish-path.c +++ b/babl/babl-fish-path.c @@ -84,9 +84,10 @@ process_conversion_path (BablList *path, static void get_conversion_path (PathContext *pc, - Babl *current_format, - int current_length, - int max_length); + Babl *current_format, + int current_length, + int max_length, + double legal_error); char * _babl_fish_create_name (char *buf, @@ -168,7 +169,8 @@ static void get_conversion_path (PathContext *pc, Babl *current_format, int current_length, - int max_length) + int max_length, + double legal_error) { if (current_length > max_length) { @@ -190,7 +192,7 @@ get_conversion_path (PathContext *pc, path_error *= (1.0 + babl_conversion_error ((BablConversion *) pc->current_path->items[i])); } - if (path_error - 1.0 <= _babl_legal_error ()) + if (path_error - 1.0 <= legal_error ) /* check this before the more accurate measurement of error - to bail earlier */ #endif @@ -213,7 +215,7 @@ get_conversion_path (PathContext *pc, if ((path_cost < ref_cost) && /* do not use paths that took longer to compute than reference */ (path_cost < pc->fish_path->fish_path.cost) && - (path_error <= _babl_legal_error ()) + (path_error <= legal_error ) ) { /* We have found the best path so far, @@ -250,7 +252,7 @@ get_conversion_path (PathContext *pc, { /* next_format is not in the current path, we can pay a visit */ babl_list_insert_last (pc->current_path, next_conversion); - get_conversion_path (pc, next_format, current_length + 1, max_length); + get_conversion_path (pc, next_format, current_length + 1, max_length, legal_error); babl_list_remove_last (pc->current_path); } } @@ -399,17 +401,31 @@ alias_conversion (Babl *babl, return 0; } -Babl * -babl_fish_path (const Babl *source, - const Babl *destination) + +static Babl * +babl_fish_path2 (const Babl *source, + const Babl *destination, + double tolerance) { Babl *babl = NULL; const Babl *sRGB = babl_space ("sRGB"); char name[BABL_MAX_NAME_LEN]; + int is_fast = 0; _babl_fish_create_name (name, source, destination, 1); babl_mutex_lock (babl_format_mutex); babl = babl_db_exist_by_name (babl_fish_db (), name); + + if (tolerance <= 0.0) + { + is_fast = 0; + tolerance = _babl_legal_error (); + } + else + is_fast = 1; + + if (!is_fast) + { if (babl) { /* There is an instance already registered by the required name, @@ -418,6 +434,7 @@ babl_fish_path (const Babl *source, babl_mutex_unlock (babl_format_mutex); return babl; } + } if ((source->format.space != sRGB) || (destination->format.space != sRGB)) @@ -484,12 +501,12 @@ babl_fish_path (const Babl *source, */ babl_in_fish_path++; - get_conversion_path (&pc, (Babl *) source, 0, max_path_length ()); + get_conversion_path (&pc, (Babl *) source, 0, max_path_length (), tolerance); /* second attempt,. at path length + 1*/ if (babl->fish_path.conversion_list->count == 0 && max_path_length () + 1 <= BABL_HARD_MAX_PATH_LENGTH) - get_conversion_path (&pc, (Babl *) source, 0, max_path_length () + 1); + get_conversion_path (&pc, (Babl *) source, 0, max_path_length () + 1, tolerance); babl_in_fish_path--; babl_free (pc.current_path); @@ -528,11 +545,45 @@ babl_fish_path (const Babl *source, /* Since there is not an already registered instance by the required * name, inserting newly created class into database. */ - babl_db_insert (babl_fish_db (), babl); + if (!is_fast) + { + babl_db_insert (babl_fish_db (), babl); + } babl_mutex_unlock (babl_format_mutex); return babl; } +const Babl * babl_fast_fish (const void *source_format, + const void *destination_format, + const char *performance) +{ + double tolerance = 0.0; + + if (!performance || !strcmp (performance, "default")) + tolerance = 0.0; // note: not _babl_legal_error() to trigger, + // right code paths in babl_fish_path2 + else if (!strcmp (performance, "exact")) + tolerance=0.0000000001; + else if (!strcmp (performance, "precise")) + tolerance=0.00001; + if (!strcmp (performance, "fast")) + tolerance=0.001; + else if (!strcmp (performance, "glitch")) + tolerance=0.01; + else { + tolerance = babl_parse_double (performance); + } + + return babl_fish_path2 (source_format, destination_format, tolerance); +} + +Babl * +babl_fish_path (const Babl *source, + const Babl *destination) +{ + return babl_fish_path2 (source, destination, 0.0); +} + static long babl_fish_path_process (Babl *babl, const void *source, diff --git a/babl/babl.h b/babl/babl.h index 080b951..5d16b35 100644 --- a/babl/babl.h +++ b/babl/babl.h @@ -104,8 +104,9 @@ const Babl * babl_space (const char *name); * multiple calls with the same icc profile will result in the * same space. * - * If a BablSpace cannot be created from the profile NULL is returned and - * a static string is set on the provided error location. + * If a BablSpace cannot be created from the profile NULL is returned and a + * static string is set on the const char *value pointed at with &value + * containing a message describing why the icc does not yield a babl space. */ const Babl *babl_space_from_icc (const char *icc_data, int icc_length, @@ -179,6 +180,25 @@ const Babl * babl_format_get_space (const Babl *format); const Babl * babl_fish (const void *source_format, const void *destination_format); + +/** + * babl_fast_fish: + * + * Creae a faster than normal fish with specified performance (and thus + * corresponding precision tradeoff), values tolerance can hold: NULL and + * "default", means do same as babl_fish(), other values understood in + * increasing order of speed gain are: + * "exact" "precise" "fast" "glitch" + * + * Fast fishes should be cached, since they are not internally kept track + * of/made into singletons by babl and many creations of fast fishes will + * otherwise be a leak. + * + */ +const Babl * babl_fast_fish (const void *source_format, + const void *destination_format, + const char *performance); + /** * babl_process: * -- 2.30.2